#!/bin/bash
#
# Copies files from `podget` and `citeulike-sync.sh` repositories to
# target directory (typically some device's mounted FS).
#
# Remembers copied files and copies only compatible type of media
#
# You can define your own media types based on file endings: "doc"->pdf,txt,html
#
# Example usage: gadget-feeder.sh doc /mnt/kindle/documents/feeds/
#

# podcasts file archive
repos=$HOME/downloads/podcasts/
citeulike=$HOME/files/lispler/citeulike/
backup=$HOME/.gadget-feeder.bak
filter="" # default file filter

leavefreeKB=10000
maxnum=0



function usage() {
  echo
  echo "Usage: $0 [-a] [-l] <media> <target>"
  echo
  echo -e "\t-n <N>    Exit after N files have been copied (don't flood me with 100 docs!)."
  echo -e "\t-a        Copy all available files, including previously copied."
  echo -e "\t-l        List candidates, do not actually copy."
  echo -e "\t-s <FILE> Save to FILE which files have already been synchronized"
  echo -e "\t-r <FILE> Reset/Restore from FILE which files have already been synchronized"
  echo -e "\t<media>   A group/type of files to copy, e.g. 'mp3' or 'doc'"
  echo -e "\t<target>  Where to copy files to, usually a mounted USB device."
}

function restore_state() {
	state="$1"
	test -f "$stste" || echo "$state: No such file or directory."

	ORIGIFS=$IFS
	IFS=`echo -en "\n\b"`
	
	for file in $(cat "$state"); do
		# podcast file archive
		chmod +t "$file"
		# citeulike archive
		prio="$(dirname "$file")"/.priority 
		test -w "$prio" && echo 0 > $prio
	done
}

function save_state() {
	state="$1"
	
	# regular podcast archive
	find -L $repos -type f $filter -perm /1000 > $state

	# citeulike archive
	for entry in $(find "$citeulike" -maxdepth 1 -type d |sed s/".*\/"//); do
	  if [ $(cat "$citeulike/$entry/.priority") -eq 0 ]; then
		  find "$citeulike/$entry/" -type f |grep -v ".priority\|[0-9]*.bib$" >> $state
		fi
	done
}

while getopts  "lan:s:r:" flag; do
  case $flag in
    "l")
      list=true
      ;;
    "a")
      sync_all=true
      ;;
    "n")
      maxnum=$OPTARG
      ;;
		"r")
			restore_state $OPTARG; exit
			;;
		"s")
			save_state $OPTARG; exit
			;;
     *)
       usage && exit
  esac
done

shift $(($OPTIND-1)) # let non-optional params start at $0
[ $# -lt 2 ] && usage && exit
media=$1
target=$2

if [ "A$list" != "Atrue" ]; then
  test -d $target || { echo "Invalid target dir."; exit; }
fi

# set to empty file so grep -v -f won't filter anything
[ "A$sync_all" != "Atrue" ] && filter="$filter ! -perm /1000"




# Search regular podcast repo depending on media type
case $media in
	"mp3")
		files="$(for ext in \*.mp3 \*.ogg \*.flac; do find -L $repos -type f \
	 	-iname "$ext" $filter; done |shuf)"
		;;
	"doc")
		files="$(for ext in \*.pdf \*.epub \*.txt \*.html; do find -L $repos -type f \
		-iname "$ext" $filter; done|shuf)"
		;;
	"vid")
		files="$(for ext in *.flv *.mp4 *.avi *.mpg; do find -L $repos -type f \
		-iname "$ext" $filter; done|shuf)"
		;;
	*)
		echo "No such media type. Try mp3 or doc."
		exit;
esac


# loop line-by-line, not word-by-word
ORIGIFS=$IFS
IFS=`echo -en "\n\b"`

for i in $files; do

	# count files..
	let maxnum--
	test $maxnum -eq 0 && exit;
	
  # if just listing files, exit here..
  if [ "A$list" = "Atrue" ]; then
		echo "$i"
		continue
	fi
	
	# check available disk space before copying..
	size=$(($(du "$i"|awk '{print $1}')+$leavefreeKB))
	space=$(df $target|tail -1 |awk '{print $4}')
	[ $size -gt $space ] && echo "Exiting due to limited remaining space:	$((${space}/1024))MB" && break

	# copy file to target
	echo Copying "${i}"...
	subdir="$(basename "$(dirname "$i")")"
	test -d "$target/$subdir" || mkdir -p "$target/$subdir"
	cp "$i" "$target/$subdir/" && chmod +t "$i"
done


# If citeulike repo is configured, add unread docs as source
if [ -d "$citeulike" ]; then
	
  # same as above, but for local citeulike repository
  for i in $(citeulike-feed.sh); do
		
		# count copied files..
		let maxnum--
		test $maxnum -eq 0 && exit;

    # if just listing files, exit here..
    if [ "A$list" = "Atrue" ]; then
      # list file
      echo "$i"
			continue
		fi
		
		# check available disk space before copying..
		size=$(($(du "$i"|awk '{print $1}')+$leavefreeKB))
		space=$(df "$target"|tail -1 |awk '{print $4}')
		[ $size -gt $space ] && echo "No space to copy $i" && break

		# count copied files..
		let maxnum--
		test $maxnum -eq 0 && exit;

		# copy file to target
		echo Copying ${i}...
		subdir="citeulike"
		test -d "$target/$subdir" || mkdir -p "$target/$subdir"
		cp "$i" "$target/$subdir/$(basename "$(dirname "$i")")-$(basename "$i")" \
			&& echo 0 > "$(dirname "$i")/.priority"
	done
fi

# with luck, touching priority files will put them to top
if [ "A$list" != "Atrue" ]; then
  for i in "$target/priority-feed/*"; do
    test -f "$i" && touch "$i";
  done
fi
